﻿using Common.Logging;
using Dubbo.Common;
using Dubbo.Common.Container;
using Dubbo.Common.Extension;
using Dubbo.Common.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Dubbo.Container.Host
{
    class Program
    {
        public static readonly string CONTAINER_KEY = "dubbo.container";

        public static readonly string SHUTDOWN_HOOK_KEY = "dubbo.shutdown.hook";

        private static readonly ILog logger = LogManager.GetLogger(typeof(Program));
        
        private static volatile bool running = true;
        private static object obj = new object();

        static void Main(string[] args)
        {
            try
            {
                if (args == null || args.Length == 0)
                {
                    string config = ConfigUtils.Get(CONTAINER_KEY);
                    args = Constants.COMMA_SPLIT_PATTERN.Split(config);
                }

                var containers = new List<IContainer>();
                for (int i = 0; i < args.Length; i++)
                {
                    containers.Add(ExtensionLoader.GetExtension<IContainer>(args[i]));
                }
                logger.Info("Use container type(" + string.Join(",", args) + ") to run dubbo serivce.");

                if ("true" == ConfigUtils.Get(SHUTDOWN_HOOK_KEY))
                {
                    AppDomain.CurrentDomain.ProcessExit += (sender, e) =>
                    {
                        foreach (var container in containers)
                        {
                            try
                            {
                                container.Stop();
                                logger.Info("Dubbo " + container.GetType().Name + " stopped!");
                            }
                            catch (Exception ex)
                            {
                                logger.Error(ex.Message, ex);
                            }
                            lock (obj)
                            {
                                running = false;
                                Monitor.Pulse(obj);
                            }
                        }
                    };
                }

                foreach (var container in containers)
                {
                    container.Start();
                    logger.Info("Dubbo " + container.GetType().Name + " started!");
                }
                Console.WriteLine(DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss]") + " Dubbo service server started!");
            }
            catch (Exception ex)
            {
                logger.Error(ex.Message, ex);
                Environment.Exit(1);
            }
            
            lock (obj)
            {
                while (running)
                {
                    try
                    {
                        Monitor.Wait(obj);
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }
        }
    }
}
